package mosdi.tests;

import junit.framework.TestCase;
import mosdi.paa.DAA;
import mosdi.paa.apps.DispensationOrderDAA;
import mosdi.util.Alphabet;

public class DispensationOrderDAATest extends TestCase {

	private static final String[] dispensationOrders = {"TGCA", "CATGATGT", "TCGAGCGCTGTG", "TACAGCAGTACAGT", "AGTGCGAGTCGCTA", "TGACGCGTGATACGCTGCGACACACACGCGCG", "GCGCACACTAGACGAGTAGCTGTATCACTAC", "CTGTACAGAGAGATATGCGCTAGCGAGCTACAG", "GTACGTCACACATCATGCGACACATATGTACA", "TCATATGTGCTGCACGACGCATGATGATGCA"};
	private static final String[] texts = {
		"TAGGGAAT",
		"TAGGGAATCGCCTTAACCATGGGGTACCCCTCGCTAATTATAGTCTGTCGGTGGCATGGGAACTGTGACATATTAGGCGCAGATCCCCTCTTATGTATCT",
		"AACACCCCATAGGTCTGCATCTTGCGAGGCGTGATCCATGTCGCGCGACCCTGGATTGATAATTAACAGAAGTTGGCCTTTACCGGGAAACACCGGGGGA",
		"GAAGTGGCCCTGCAAAAATGCAAGCCTAGCTATATTTGGATGACCAGGATTCTCTCGAACGGTACTGGTGTGAAACCTGAAAGCTGTTACTCTGAAGCAT",
		"CCAGCGTCGAGTTTCGCGTGGACACGCCGTCAAGATGACTCTGACCTGGCATTTAAAGCTGACCTACACCACGACCAGAACAAGTCGTCGTCCTTTTCGT",
		"GTCCGGCTTCCGCAAGCCGACTGTGAGCATCAGTCAGTTGAATTTACAGGCCAATGCATCCACGGGCTCTATTTAACAAATTTTGTGGGCTACTTGGGGT",
		"GGATGGCTTCCTCTACACCTAGCGAGTGGATACATGTTTACGCTCGTCCACTCTGCGCGAATCACGTCTGCATACATTCCCTATCACCTCAAAGCCTCAT",
		"ACCCCCCGCTTTGAAAGTCTCGTCCCCAAGATACTGCCTAGGTAATATGCAGAAGGTGAGTAGCGGCGCCGAGCCCTCCAACATGTATATTGTCGATGGT",
		"CCGAAGTCGATCGATAATACATCTGGGTAATACTGCCCATTCAAACCTTGAAGGACAAATCAAGGAGTTGCGTACGCTGCGATTGCTTGCCTATTACCCG",
		"TTCGGAAGCTGCATCTGATACTCTCCTGTAGAGGGAGCGCACACGCACACAAGGCAGGGTACGGCATAGTATATAGGCGTGGCCCGCATCTACGTACACT",
		"CTAGACGCAGGTATAGCCAGGCGAAATGGTGCTGTTGCTTACGATTCGATATCGGTGGAATGACACGTTTCCACTATTGTCGCTTCTCCGATATTTCCCT"
	};
	
	private int computeFlowCount(int[] dispensationOrder, int[] string) {
		// current position in dispensation order
		int j = 0;
		// number of needed flows. start at one because it takes one
		// flow to reach cycle 0
		int flows = 1;
		for (int i=0; i<string.length; ++i) {
			int k = 0;
			while ((dispensationOrder[j]!=string[i]) && (k<dispensationOrder.length)) {
				j = (j+1) % dispensationOrder.length;
				k += 1;
			}
			if (k == dispensationOrder.length) {
				throw new IllegalArgumentException();
			}
			flows += k;
		}
		return flows;
	}

	public void testSimpleFlowCountComputation() {
		Alphabet alphabet = Alphabet.getDnaAlphabet();
		String order = "ACGT";
		int[] intOrder = alphabet.buildIndexArray(order);
		DAA daa = new DispensationOrderDAA(alphabet.size(),intOrder,1000);
		final String[] testTexts = { "CA", "GA", "GC", "TA", "TC", "TG" };
		for (String text : testTexts) {
			int[] intText = alphabet.buildIndexArray(text);
			assertTrue(daa.computeValue(intText) > 4);
		}
	}
	
	public void testFlowCountComputation() {
		Alphabet alphabet = Alphabet.getDnaAlphabet();
		for (String order : dispensationOrders) {
			int[] intOrder = alphabet.buildIndexArray(order);
			DAA daa = new DispensationOrderDAA(alphabet.size(),intOrder,1000);
			for (String text : texts) {
				int[] intText = alphabet.buildIndexArray(text);
				assertEquals(computeFlowCount(intOrder, intText), daa.computeValue(intText));
			}
			
		}
	}
	
}
